//
// Created by chaseaishang on 23-4-10.
//
#include "Render/Renderer.h"
#include "TestCubeTex.h"
#include "imgui.h"
#include "Event.h"
#include "KeyEvent.h"



#include "glm/glm.hpp"
#include "glm/gtc/matrix_transform.hpp"
test::TestCubeTex::~TestCubeTex() {

}
test::TestCubeTex::TestCubeTex()
        :m_Proj(glm::ortho(0.0f, 960.0f, 0.0f, 720.0f, -400.0f, 400.0f)),
         m_View(glm::translate(glm::mat4(1.0f), glm::vec3(0, 0, 0))),
         m_TranslationA(glm::vec3(200, 200, 0)), m_TranslationB(glm::vec3(400, 200, 0)),
         m_rotate{0,0,0}
{
    GLCall(glEnable(GL_BLEND));
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LESS);
    GLCall(glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
    float positions[] = {
            -1.0f, -1.0f, 1.0f,           // 0
            1.0f, -1.0f, 1.0f,           // 1
            1.0f, 1.0f,1.0f,         // 2
            -1.0f, 1.0f, 1.0f,         // 3
            -1.0f, -1.0f, -1.0f,             //4
            1.0f,-1.0f,-1.0f,               //5
            1.0f,1.0f,-1.0f,               //6
            -1.0f,1.0f,-1.0f                   //7

    };
    unsigned int indices[] = {
            //front
            0, 1, 2,
            2, 3, 0,
            //back
            4,5,6,
            6,7,4,
            //left
            4,0,3,
            3,7,4,
            //right
            1,5,6,
            6,2,1,
            //top
            3,2,6,
            6,7,3,
            //bottom
            0,1,5,
            5,4,0
    };
    GLCall(glEnable(GL_DEPTH_TEST));
    GLCall(glEnable(GL_BLEND));
    GLCall(glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));

    m_VAO = std::make_unique<VertexArray>();

    m_VertexBuffer = std::make_unique<VertexBuffer>(positions, 5 * 8 * sizeof(float));
    VertexBufferLayout layout;
    layout.Push<float>(3);
    m_VAO->AddBuffer(*m_VertexBuffer, layout);

    m_IndexBuffer = std::make_unique<IndexBuffer>(indices, 36);

    m_Shader = std::make_unique<Shader>("../res/shaders/CubeTexture.shader");
    m_Shader->Bind();
    m_Shader->SetUniform4f("u_Color", 0.2f, 0.3f, 0.8f, 1.0f);
    m_Shader->SetUniform1i("u_Texture", 0);

    m_Texture = std::make_unique<CubeTexture>("../res/textures/container.jpg");
}
void test::TestCubeTex::OnEvent(Event &e)
{
    if(e.IsInCategory(EventCategory::EventCategoryApplication))
    {
        return;
    }
    EventDispatcher dispatcher(e);
    dispatcher.Dispatch<KeyPressedEvent>(
            [&](KeyPressedEvent&e)
            {

                return true;
            }
    );
    dispatcher.Dispatch<KeyReleasedEvent>(
            [&](KeyReleasedEvent&e)
            {

                return true;
            }
    );

}

void test::TestCubeTex::OnRender()
{
    GLCall(glClearColor(0.0f, 0.0f, 0.0f, 1.0f));
    GLCall(glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT));

    Renderer renderer;

    m_Texture->Bind();

    {

        glm::mat4 model = glm::translate(glm::mat4(1.0f), m_TranslationA);
        model=glm::scale(model,glm::vec3(100,100,100));
        model=glm::rotate(model, glm::radians(m_rotate[0]), glm::vec3(1.0, 0.0, 0.0));
        model=glm::rotate(model, glm::radians(m_rotate[1]), glm::vec3(0.0, 1.0, 0.0));
        model=glm::rotate(model, glm::radians(m_rotate[2]), glm::vec3(0.0, 0.0, 1.0));
        glm::mat4 mvp = m_Proj * m_View * model;

        m_Shader->Bind();
        m_Shader->SetUniformMat4f("u_MVP", mvp);

        renderer.Draw(*m_VAO, *m_IndexBuffer, *m_Shader);
    }

    {
        glm::mat4 model = glm::translate(glm::mat4(1.0f), m_TranslationB);

        model=glm::rotate(model, glm::radians(m_rotate[0]), glm::vec3(1.0, 0.0, 0.0));
        model=glm::rotate(model, glm::radians(m_rotate[1]), glm::vec3(0.0, 1.0, 0.0));
        model=glm::rotate(model, glm::radians(m_rotate[2]), glm::vec3(0.0, 0.0, 1.0));
        model=glm::scale(model,glm::vec3(100,100,100));
        glm::mat4 mvp = m_Proj * m_View * model;

        m_Shader->Bind();
        m_Shader->SetUniformMat4f("u_MVP", mvp);

        renderer.Draw(*m_VAO, *m_IndexBuffer, *m_Shader);
    }

}


void test::TestCubeTex::OnImGuiRender()
{
    float min[3]={0,0,-1};
    float max[3]={860,620,1};
    ImGui::mySliderFloat3("m_TranslationA", &m_TranslationA.x, min, max,"%.3f" ,0);
    //ImGui::SliderFloat3("m_TranslationA", &m_TranslationA.x, 0.0f, 960.0f);
    ImGui::SliderFloat3("m_TranslationB", &m_TranslationB.x, 0.0f, 960.0f);
    ImGui::SliderFloat3("Rotate_XYZ", m_rotate, 0.0f, 360.0f);

    ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate);

}



void test::TestCubeTex::OnUpdate(float deltaTime) {

}


